Unlike Knights of a Round Table, Knights of a Polygonal Table deprived of nobility and happy to kill each other. But each knight has some power and a knight can kill another knight if and only if his power is greater than the power of victim. However, even such a knight will torment his conscience, so he can kill no more than kk other knights. Also, each knight has some number of coins. After a kill, a knight can pick up all victim's coins.
Now each knight ponders: how many coins he can have if only he kills other knights?
You should answer this question for each knight.
The first line contains two integers nn and kk (1≤n≤105,0≤k≤min(n−1,10))(1≤n≤105,0≤k≤min(n−1,10)) — the number of knights and the number kk from the statement.
The second line contains nn integers p1,p2,…,pnp1,p2,…,pn (1≤pi≤109)(1≤pi≤109) — powers of the knights. All pipi are distinct.
The third line contains nn integers c1,c2,…,cnc1,c2,…,cn (0≤ci≤109)(0≤ci≤109) — the number of coins each knight has.
Print nn integers — the maximum number of coins each knight can have it only he kills other knights.
题解:
按照a的值升序排列,在i前面的a都小于ai,所以去1~i-1 这段区间中前k大的k个数。
因为k<=10, 因此可以用线段树来维护区间前k大。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+7;
struct node
{
int a,b,id;
}t[maxn];
struct pp
{
ll ans;int id;
}s[maxn];
vector<int>G[maxn<<2];
int n,k,w[maxn],tol;
bool cmp(const node &x,const node &y)
{
return x.a<y.a;
}
bool cmp1(const pp &x,const pp &y)
{
return x.id<y.id;
}
void push_up(int rt)
{
int L1=G[rt<<1].size(),L2=G[rt<<1|1].size(),l1=0,l2=0;
while(G[rt].size()<k)
{
if(l1<L1&&l2<L2)
{
if(G[rt<<1][l1]>G[rt<<1|1][l2])
G[rt].push_back(G[rt<<1][l1++]);
else
G[rt].push_back(G[rt<<1|1][l2++]);
}
else if(l1<L1)
{
G[rt].push_back(G[rt<<1][l1++]);
}
else if(l2<L2)
{
G[rt].push_back(G[rt<<1|1][l2++]);
}
else break;
}
}
void build(int l,int r,int rt)
{
if(l==r)
{
G[rt].push_back(t[l].b);
return;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
push_up(rt);
}
void query(int L,int R,int l,int r,int rt)
{
if(l>=L&&r<=R)
{
for(int i=0;i<G[rt].size();i++)
w[tol++]=G[rt][i];
return;
}
int mid=(l+r)>>1;
if(L<=mid)query(L,R,l,mid,rt<<1);
if(R>mid)query(L,R,mid+1,r,rt<<1|1);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&t[i].a);
t[i].id=i;
}
for(int i=1;i<=n;i++)
scanf("%d",&t[i].b);
sort(t+1,t+n+1,cmp);
build(1,n,1);
s[1].ans=t[1].b;s[1].id=t[1].id;
for(int i=2;i<=n;i++)
{
tol=0;
s[i].ans=t[i].b;
query(1,i-1,1,n,1);
sort(w,w+tol);
for(int j=tol-1,h=0;h<k&&j>=0;j--,h++)
s[i].ans+=w[j];
s[i].id=t[i].id;
}
sort(s+1,s+n+1,cmp1);
for(int i=1;i<=n;i++)
printf("%lld ",s[i].ans);
return 0;
}